package com.myaxuan.configuration.dynamicdatasource;


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.myaxuan.common.DataSourceEnum;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by pc255 on 2018/1/24.
 */

@Configuration
public class DataSource {
	@Bean("master")
	@Primary
	@ConfigurationProperties(prefix = "spring.datasource.druid.master")
	public DruidDataSource master() {
		return DruidDataSourceBuilder.create().build();
	}

	/**
	 * lesser  data source.
	 * @return the data source
	 */
	@Bean("lesser")
	@ConfigurationProperties(prefix = "spring.datasource.druid.lesser")
	public DruidDataSource lesser() {
		return DruidDataSourceBuilder.create().build();
	}

	/**
	 * Dynamic data source.
	 * @return the data source
	 */
	@Bean("dynamicDataSource")
	public DynamicRoutingDataSource dynamicDataSource() {
		DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
		Map<Object, Object> dataSourceMap = new HashMap<>(2);
		dataSourceMap.put(DataSourceEnum.master.toString(), master());
		dataSourceMap.put(DataSourceEnum.lesser.toString(), lesser());

		// 将 master 数据源作为默认指定的数据源
		dynamicRoutingDataSource.setDefaultTargetDataSource(master());
		// 将 master 和 slave 数据源作为指定的数据源
		dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);

		// 将数据源的 key 放到数据源上下文的 key 集合中，用于切换时判断数据源是否有效
		//DynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());

		// 将 Slave 数据源的 key 放在集合中，用于轮循
		//DynamicDataSourceContextHolder.slaveDataSourceKeys.addAll(dataSourceMap.keySet());
		//DynamicDataSourceContextHolder.slaveDataSourceKeys.remove(DataSourceKey.master.name());
		return dynamicRoutingDataSource;
	}

	/**
	 * 配置 SqlSessionFactoryBean
	 * @ConfigurationProperties 在这里是为了将 MyBatis 的 mapper 位置和持久层接口的别名设置到
	 * Bean 的属性中，如果没有使用 *.xml 则可以不用该配置，否则将会产生 invalid bond statement 异常
	 *
	 * @return the sql session factory bean
	 */
	@Bean
	@ConfigurationProperties(prefix = "mybatis")
	public SqlSessionFactoryBean sqlSessionFactoryBean() {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		// 配置数据源，此处配置为关键配置，如果没有将 dynamicDataSource 作为数据源则不能实现切换
		sqlSessionFactoryBean.setDataSource(dynamicDataSource());
		return sqlSessionFactoryBean;
	}

	/**
	 * 注入 DataSourceTransactionManager 用于事务管理
	 */
	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dynamicDataSource());
	}
}
